package cn.mianshiyi.braumdatasource;


import cn.mianshiyi.braumclient.ratelimit.EasyLimitContext;
import cn.mianshiyi.braumclient.ratelimit.EasyRateLimiter;
import cn.mianshiyi.braumclient.ratelimit.rule.LimitRuleConfig;
import cn.mianshiyi.braumclient.utils.EasyStringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

/**
 * @author shangqing.liu
 */
public abstract class AbstractDataSource {

    private static final Logger LOGGER = LoggerFactory.getLogger(AbstractDataSource.class);

    protected abstract List<LimitRuleConfig> loadAllConfig();

    public void initConfig() {
        List<LimitRuleConfig> limitRuleConfigs = loadAllConfig();
        if (limitRuleConfigs == null) {
            return;
        }
        for (LimitRuleConfig config : limitRuleConfigs) {
            EasyLimitContext.RATE_LIMIT_INIT_OUT_RULE_MAP.put(config.getName(), config);
        }
    }

    public boolean updateConfig(List<LimitRuleConfig> configList) {
        for (LimitRuleConfig config : configList) {
            checkConfig(config);
            EasyRateLimiter easyRateLimiter = EasyLimitContext.RATE_LIMITER_MAP.get(config.getName());
            if (easyRateLimiter == null) {
                if (LOGGER.isWarnEnabled()) {
                    LOGGER.warn("update limit rule limit source not exist,name:{}", config.getName());
                }
                continue;
            }
            if (LOGGER.isInfoEnabled()) {
                LOGGER.info("update limit rule,name:{},permitsPerSecond:{}", config.getName(),
                        config.getPermitsPerSecond());
            }
            easyRateLimiter.modify(config.getPermitsPerSecond());
        }
        return true;
    }

    private void checkConfig(LimitRuleConfig config) {
        if (config == null) {
            throw new IllegalArgumentException("limit config not allow null");
        }
        if (EasyStringUtil.isEmpty(config.getName())) {
            throw new IllegalArgumentException("limit config name not allow null");
        }
        if (config.getPermitsPerSecond() < 0d) {
            throw new IllegalArgumentException("limit config permitsPerSecond not allow lt 0d");
        }
    }

}
